﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;

namespace DBUtility.Standard
{
    /// <summary>
    /// 
    /// </summary>
    internal abstract class DBHelper : IDBHelper
    {
        public static IDbConnection dbConnection;
        /// <summary>
        /// 数据库连接字符串
        /// </summary>
        public string connectionString = string.Empty;

        /// <summary>
        /// 生成DbProviderFactory对象
        /// </summary>
        /// <param name="connStr">连接字符串</param>
        public DBHelper(string connStr)
        {
            this.connectionString = connStr;
        }

        public abstract void CreateConnection();
        public abstract int ExecuteNonQuery(CommandType cmdType, string cmdText, params DbParameter[] cmdParams);

        public abstract int ExecuteNonQuery(DbTransaction trans, CommandType cmdType, string cmdText, params DbParameter[] cmdParams);

        public abstract DataSet ExecuteQuery(CommandType cmdType, string cmdText, params DbParameter[] cmdParams);

        public abstract DataSet ExecuteQuery(DbTransaction trans, CommandType cmdType, string cmdText, params DbParameter[] cmdParams);

        public abstract DataTable ExecuteNQuery(CommandType cmdType, string cmdText, params DbParameter[] cmdParams);

        public abstract DataTable ExecuteNQuery(DbTransaction trans, CommandType cmdType, string cmdText, params DbParameter[] cmdParams);

        public abstract List<List<string>> ExecuteLQuery(CommandType cmdType, string cmdText, params DbParameter[] cmdParams);

        public abstract List<List<string>> ExecuteLQuery(DbTransaction trans, CommandType cmdType, string cmdText, params DbParameter[] cmdParams);

        public abstract DbDataReader ExecuteReader(CommandType cmdType, string cmdText, params DbParameter[] cmdParams);

        public abstract DbDataReader ExecuteReader(DbTransaction trans, CommandType cmdType, string cmdText, params DbParameter[] cmdParams);

        public abstract object ExecuteScalar(CommandType cmdType, string cmdText, params DbParameter[] cmdParams);

        public abstract object ExecuteScalar(DbTransaction trans, CommandType cmdType, string cmdText, params DbParameter[] cmdParams);
        public abstract DbParameter CreateParam(string paramName, DbType dbType, object value, int size, ParameterDirection direction);

        public DbParameter CreateInParam(string paramName, DbType dbType, object value, int size)
        {
            return CreateParam(paramName, dbType, value, size, ParameterDirection.Input);
        }

        public DbParameter CreateInParam(string paramName, DbType dbType, object value)
        {
            return CreateParam(paramName, dbType, value, 0, ParameterDirection.Input);
        }

        public DbParameter CreateOutParam(string paramName, DbType dbType, int size)
        {
            return CreateParam(paramName, dbType, null, size, ParameterDirection.Output);
        }

        public DbParameter CreateOutParam(string paramName, DbType dbType)
        {
            return CreateParam(paramName, dbType, null, 0, ParameterDirection.Output);
        }

        public DbParameter CreateReturnParam(string paramName, DbType dbType, int size)
        {
            return CreateParam(paramName, dbType, null, size, ParameterDirection.ReturnValue);
        }

        public DbParameter CreateReturnParam(string paramName, DbType dbType)
        {
            return CreateParam(paramName, dbType, null, 0, ParameterDirection.ReturnValue);
        }

        /// <summary>
        /// 获取一个Command对象
        /// </summary>
        /// <param name="con">数据库的连接</param>
        /// <param name="cmd">表示要对数据源执行的Transact-SQL语句或存储过程</param>
        /// <param name="commandTyp">命令字符串类型</param>
        /// <param name="commandText">执行语句</param>
        /// <param name="trans">事务</param>
        /// <param name="cmdParams">命令参数列表</param>
        /// <returns>返回Command对象</returns>
        public void PrepareCmd(IDbCommand command, CommandType commandTyp, string commandText, DbTransaction trans, params DbParameter[] commandParameters)
        {
            if (dbConnection == null)
                CreateConnection();

            if (dbConnection.State != ConnectionState.Open)
                dbConnection.Open();

            command.Connection = dbConnection;
            command.CommandType = commandTyp;

            command.CommandText = commandText;

            if (trans != null)
                command.Transaction = trans;

            if (commandParameters != null)
            {
                //command.Parameters.Add(commandParameters);
                foreach (DbParameter p in commandParameters)
                {
                    if (p != null)
                    {
                        // Check for derived output value with no value assigned
                        if ((p.Direction == ParameterDirection.InputOutput ||
                            p.Direction == ParameterDirection.Input) &&
                            (p.Value == null))
                        {
                            p.Value = DBNull.Value;
                        }
                        command.Parameters.Add(p);
                    }
                }
            }
        }
    }
}
